<?php
/**
 * Created by PhpStorm.
 * User: 我型我素
 * Date: 2018/1/23
 * Time: 9:58
 */

namespace App\Services\Bonus;

use App\Repositories\Bonus\BonusConfigRepository;
use App\Repositories\Bonus\BonusTypeRepository;
use App\Repositories\Bonus\UserBonusRepository;
use App\Repositories\Goods\GoodsRepository;
use App\Repositories\Louxiaoer\LouxiaoerLandmarkRepository;
use App\Services\Category\CategoryService;

class BonusService
{
    /**
     * @var BonusTypeRepository
     */
    protected $bonusTypeRepository;

    /**
     * @var UserBonusRepository
     */
    protected $userBonusRepository;

    /**
     * @var BonusConfigRepository
     */
    protected $bonusConfigRepository;

    /**
     * @var LouxiaoerLandmarkRepository
     */
    protected $landmarkRepository;

    /**
     * @var GoodsRepository
     */
    protected $goodsRepository;


    /**
     * @var CategoryService
     */
    protected $categoryService;

    /**
     * 可用红包列表
     * @var array
     */
    protected $can_use_bonus_list = [];

    /**
     * 是否包含促销商品
     * @var
     */
    protected $has_promote_goods;

    /**
     * 商品总价
     * @var
     */
    protected $goods_amount;
    /**
     * 商品总价（不包括促销商品）
     * @var
     */
    protected $goods_amount_not_in_promote;

    /**
     * 用户收货地址地标
     * @var
     */
    protected $land_mark = [];

    /**
     * 是否可用
     * @var bool
     */
    protected $use_flag = true;

    /**
     * 是否限制
     * @var bool
     */
    protected $bonus_flag = false;

    /**
     * 订单商品
     * @var
     */
    protected $cart_goods;

    /**
     * 商品id
     * @var
     */
    protected $goods_id_list = [];

    /**
     * 分类id
     * @var
     */
    protected $goods_cat_id_list = [];

    /**
     * 品牌id
     * @var
     */
    protected $goods_brand_id_list = [];

    /**
     * 红包限制信息
     * @var
     */
    protected $bonus_limit_info;
    /**
     * 红包备注
     * @var array
     */
    protected $remark = [];

    public function __construct(BonusTypeRepository $bonusTypeRepository,
                                UserBonusRepository $userBonusRepository,
                                BonusConfigRepository $bonusConfigRepository,
                                LouxiaoerLandmarkRepository $landmarkRepository,
                                GoodsRepository $goodsRepository,
                                CategoryService $categoryService)
    {
        $this->bonusTypeRepository = $bonusTypeRepository;
        $this->userBonusRepository = $userBonusRepository;
        $this->bonusConfigRepository = $bonusConfigRepository;
        $this->landmarkRepository = $landmarkRepository;
        $this->goodsRepository = $goodsRepository;

        $this->categoryService = $categoryService;
    }

    /**
     * 我的红包列表
     * @author yangzhic
     * @param int $userId
     * @param int $show_all (1：显示所有红包，2：只显示未过期的红包,3：只显示过期红包)
     * @return mixed
     */
    public function getUserBonus(int $userId, int $show_all){
        $bonus_list = $this->userBonusRepository->getUserBonusByUserId($userId,$show_all);

        if(!empty($bonus_list)){
            foreach($bonus_list as $key=>$bonus){
                $bonus->use_start_date = local_to_time($bonus->use_start_date);
                if($bonus->deadline>0){
                    $bonus->use_end_date = local_to_time($bonus->deadline);
                }else{
                    $bonus->use_end_date = local_to_time($bonus->use_end_date);
                }

                if($bonus->is_limit_buy==1){
                    $bonus_config = $this->userBonusRepository->getBonusConfigByTypeId($bonus->bonus_type_id);
                    $bonus_config_list = [];
                    foreach ($bonus_config as $cfg_key=>$cfg_data){
                        if($cfg_data['status']==0){
                            continue;
                        }
                        switch ($cfg_data['act_rang'])	{
                            case 1:
                                $bonus_config[$cfg_key]['typename'] = "分类";
                                $bonus_config[$cfg_key]['name'] = $cfg_data['cat_name'];
                            break;
                            case 2:
                                $bonus_config[$cfg_key]['typename'] = "品牌";
                                $bonus_config[$cfg_key]['name'] = $cfg_data['brand_name'];
                            break;
                            case 3:
                                $bonus_config[$cfg_key]['typename'] = "商品";
                                $bonus_config[$cfg_key]['name'] = $cfg_data['goods_name'];
                            break;
                        }
                        $bonus_config_list[] = $bonus_config[$cfg_key];
                    }
                    $bonus->limit_info = $bonus_config_list;
                }else{
                    $bonus->limit_info = [];
                }

                $bonus->place_order_start_date = convert_to_time($bonus->place_order_start_date);
                $bonus->place_order_end_date = convert_to_time($bonus->place_order_end_date);
                $bonus->shipping_start_date = convert_to_time($bonus->shipping_start_date);
                $bonus->shipping_end_date = convert_to_time($bonus->shipping_end_date);
                $bonus->shopping_type_info='';
                switch ($bonus->shopping_type){
                    case 0:
                        $bonus->shopping_type_info='全场通用';
                    break;
                    case 1:
                        $bonus->shopping_type_info='仅限送货到家使用';
                    break;
                    case 2:
                        $shopping_type_info='线下门店';
                        if($bonus->shopping_type_info!=0){
                            $shop_info=config('shidexian.shop_info');
                            $shopping_type_info_arr=explode(",",$bonus->shopping_type_info);
                            $shopping_type_info=[];
                            foreach($shopping_type_info_arr as $item){
                                $shopping_type_info[]=$shop_info[$item]['name'];
                            }
                            $shopping_type_info=implode(",",$shopping_type_info);
                        }
                        $bonus->shopping_type_info='仅限'.$shopping_type_info.'使用';
                }
            }
        }

        return $bonus_list->toArray();
    }


    /**
     * 取订单可用红包列表
     * @param int $userId
     * @param array $param
     * @return mixed
     */
    public function getOrderCanUseBonus(int $userId,array $param=array()){
        $this->can_use_bonus_list = $this->userBonusRepository->getCanUseBonus($userId);
        //数据中的对象转换为数组格式
        $this->can_use_bonus_list = array_map('get_object_vars',$this->can_use_bonus_list);

        $this->can_use_bonus_list = $this->checkCanUseBonus($param);

        return $this->can_use_bonus_list;
    }


    /**
     * @param $param
     * @return array
     */
    public function checkCanUseBonus($param){
        //初始商品化数据
        $this->initGoodsData($param);
        $now_time = gm_time();
        if(!empty($this->can_use_bonus_list) && count($param['cart_goods']) >0){
            foreach($this->can_use_bonus_list as $key=>$bonus){
                //初始化红包参数
                $this->initStatus();
                //检查是门店限制
                $this->checkByShop($bonus,$param);
                //检查有效期
                $this->checkByTime($bonus,$now_time);
                //检查地标限制
                $this->checkByLandmark($bonus,$param);
                //检查促销支持
                $this->checkByPromote($bonus);
                //检查配送以及付款时间限制
                $this->checkByPlaceAndShippingDate($bonus,$param);
                //检查商品限制
                $this->checkByBonusConfig($bonus);
                //处理红包数据
                $this->getBonusInfo($key);
            }
        }

        return $this->can_use_bonus_list;
    }

    /**
     * @author yangzhic
     * @param $bonus_key
     */
    public function getBonusInfo($bonus_key){
        $this->can_use_bonus_list[$bonus_key]['limit_info'] = $this->bonus_limit_info;
        $this->can_use_bonus_list[$bonus_key]['remark'] = $this->remark;
        if(!empty($this->remark)){
            $bonus_can_use = 0;
        }else{
            $bonus_can_use = 1;
        }
        $this->can_use_bonus_list[$bonus_key]['can_use'] = $bonus_can_use;
    }

    /**
     * @author yangzhic
     */
    public function initStatus(){
        $this->remark = [];
    }

    /**
     * @author yangzhic
     * @param $param = [
     * 'cart_goods' //购物车商品列表信息
     * 'goods_amount'  //订单商品总金额
     * ]
     */
    public function initGoodsData($param){
        $this->cart_goods = $param['cart_goods'];
        $this->goods_amount = $param['goods_amount'];

        $goods_ids = array();
        $this->goods_amount_not_in_promote = $this->goods_amount;

        $this->has_promote_goods = 0;
        foreach ($this->cart_goods as $goods){
            $goods_ids[] = $goods['goods_id'];
            //计算不包括促销商品的总金额
            if($goods['giving']==4){
                $this->goods_amount_not_promote-=$goods['goods_price']*$goods['goods_number'];
                $this->has_promote_goods = 1;
            }
        }

        //获取当前购物车中商品id,所属分类以及品牌
    	$data = $this->goodsRepository->getGoodsByIds($goods_ids);

    	foreach ($data as $val){
            if(!in_array($val["goods_id"], $this->goods_id_list)){
                $this->goods_id_list[] = $val["goods_id"];
            }
            if(!in_array($val["cat_id"], $this->goods_cat_id_list)){
                $this->goods_cat_id_list[] = $val["cat_id"];
            }
            if(!in_array($val["brand_id"], $this->goods_brand_id_list)){
                $this->goods_brand_id_list[] = $val["brand_id"];
            }
            foreach($this->cart_goods as $g_key=>$goods_val){
                if($goods_val['goods_id'] == $val['goods_id']){
                    $this->cart_goods[$g_key]['cat_id'] = $val["cat_id"];
                    $this->cart_goods[$g_key]['brand_id'] = $val["brand_id"];
                }
            }
        }
    }

    /**
     * 检查红包有效期
     * @param $bonus
     * @param $time
     */
    public function checkByTime($bonus,$time){
        if(empty($time)){
            $time = gm_time();
        }
        if($time<$bonus['use_start_date']){
            if(!empty($bonus['deadline'])){
                $this->remark[] = "使用有效期为".local_date('Y-m-d H:i:s',$bonus['use_start_date'])."至".local_date('Y-m-d H:i:s',$bonus['deadline']);
                $this->use_flag = false;
            }else{
                $this->remark[] = "使用有效期为".local_date('Y-m-d H:i:s',$bonus['use_start_date'])."至".local_date('Y-m-d H:i:s',$bonus['use_end_date']);
                $this->use_flag = false;
            }
        }
        if($bonus['deadline']>0 && $time>$bonus['deadline']){
            $this->remark[] = "使用有效期为".local_date('Y-m-d H:i:s',$bonus['get_time'])."至".local_date('Y-m-d H:i:s',$bonus['deadline']);
            $this->use_flag = false;

        }elseif($bonus['deadline'] == 0  && $time > $bonus['use_end_date']){
            if(empty($bonus['get_time'])){
                $this->remark[] = "使用有效期为".local_date('Y-m-d H:i:s',$bonus['use_start_date'])."至".local_date('Y-m-d H:i:s',$bonus['use_end_date']);
                $this->use_flag = false;
            }else{
                $this->remark[] = "使用有效期为".local_date('Y-m-d H:i:s',$bonus['get_time'])."至".local_date('Y-m-d H:i:s',$bonus['use_end_date']);
                $this->use_flag = false;
            }
        }
    }

    /**
     * 检查红包促销支持
     * @author yangzhic
     * @param $bonus
     */
    public function checkByPromote($bonus){
        //如果红包使用订单总金额，设置不包括促销商品，则不可以使用
        if(!$bonus['include_promotion'] && $bonus['min_goods_amount']-$this->goods_amount_not_in_promote>0){
            $need_price = round($bonus['min_goods_amount']-$this->goods_amount_not_in_promote,2);
            $this->remark[] = "还差".$need_price."元可用(不包含促销商品)";
            $this->use_flag = false;
        }elseif($bonus['include_promotion'] && $bonus['min_goods_amount']-$this->goods_amount>0){
            $need_price = round($bonus['min_goods_amount']-$this->goods_amount,2);
            $this->remark[] = "还差".$need_price."元可用";
            $this->use_flag = false;
        }
    }

    /**
     * @role 获取红包配置
     * @author Jianhe
     * @param $bonus_id
     * @return mixed
     */
    public function getBonusTypeConfig($bonus_id){
        $bonus=$this->BonusTypeRepository->getBonusById($bonus_id);
        $bonus['config'] = $this->userBonusRepository->getBonusConfigByTypeId($bonus["type_id"]);
        return $bonus;
        
    }

    /**
     * @author yangzhic
     * @param $bonus
     */
    public function checkByBonusConfig($bonus){
        $cart_goods_info_temp = $this->cart_goods;
        $config = $this->userBonusRepository->getBonusConfigByTypeId($bonus["type_id"]);

        $this->bonus_flag = false;
        $bonus_config_list = array();
        if($bonus['is_limit_buy'] && !empty($config)){

            foreach ($config as $cfg_key=>$cfg_val){
                switch ($cfg_val['act_rang']){
                    case 1:
                        //获取当前分类的所有子分类
                        $sub_cate_list = $this->categoryService->getAllSubCateId($cfg_val['cate_id']);
                        $cate_result = array_intersect($sub_cate_list,$this->goods_cat_id_list);
                        if(count($cate_result)>0){
                            $cart_goods_info_temp =$this->getBonusMismatchGoods($cart_goods_info_temp,'cat_id',$cfg_val['cate_id'],$bonus['include_promotion']);
                            $this->bonus_flag = true;
                        }
                        $config[$cfg_key]['typename'] = "分类";
                        $config[$cfg_key]['name'] = $cfg_val['cat_name'];
                    break;
                    case 2:
                        if(in_array($cfg_val['brand_id'], $this->goods_brand_id_list)){
                            $cart_goods_info_temp = $this->getBonusMismatchGoods($cart_goods_info_temp,'brand_id',$cfg_val['brand_id'],$bonus['include_promotion']);
                            $this->bonus_flag = true;
                        }
                        $config[$cfg_key]['typename'] = "品牌";
                        $config[$cfg_key]['name'] = $cfg_val['brand_name'];
                    break;
                    case 3:
                        if(in_array($cfg_val['goods_id'], $this->goods_id_list)){
                            $cart_goods_info_temp = $this->getBonusMismatchGoods($cart_goods_info_temp,'goods_id',$cfg_val['goods_id'],$bonus['include_promotion']);
                            $this->bonus_flag = true;
                        }
                        $config[$cfg_key]['typename'] = "商品";
                        $config[$cfg_key]['name'] = $cfg_val['goods_name'];
                    break;
                }
                $bonus_config_list[] = $config[$cfg_key];
            }
            $this->bonus_limit_info = $bonus_config_list;
        }else{
            $this->bonus_limit_info = array();
            $cart_goods_info_temp = array();
            $this->bonus_flag = true;
        }

        if($this->bonus_flag){
            //统计符合红包条件的商品总价
            $bonus_goods_amount = $this->getBounsGoodsTotalPrice($cart_goods_info_temp,$this->goods_amount);
            if($bonus['min_goods_amount']-$bonus_goods_amount>0){
                if($bonus['is_limit_buy']){
                    $need_price = round($bonus['min_goods_amount']-$bonus_goods_amount,2);
                    $this->remark[] = "只适用部分商品,还差".$need_price."元可用";
                }
                if(!$bonus['include_promotion'] && $this->has_promote_goods){
                    $this->remark[] = "订单内包含促销商品不可使用";
                }
                $this->bonus_flag = false;
            }
        }else{
            $this->remark[] = "订单内无适用商品/品类";
        }
    }

    /**
     * 检查是否符合可使用地标
     * @param $bonus
     * @param $param = [
     * 'region_id'=>$fac_address['wdr_id'],     //区域id
     * 'name'=>$useraddress['sign_building']    //用户地址目标建筑
     * ]
     */
    public function checkByLandmark($bonus,array $param){
        if(empty($this->land_mark) && (!empty($param['region_id']) && !empty($param['name']))){
            $this->land_mark = $this->landmarkRepository->getLandMark($param);
        }

        //如果设置了地标范围，不在地标范围内，则不可以使用
        if($bonus['is_limit_landmark']==1){
            if(!empty($bonus['act_landmark_ext'])){
                $act_landmark_ext = explode(',',$bonus['act_landmark_ext']);
                if(empty($this->land_mark) || !in_array($this->land_mark['id'],$act_landmark_ext)){
                    $this->remark[] = "收货地址就不在红包可用范围内";
                    $this->use_flag = false;
                }
            }
        }
    }

    /**
     * 检查是否符合门店限制
     * @param $bonus
     * @param $param = [
     * 'shopping_type',       //配送方式:1,仅送货到家可用，2：到店自提，
     * 'wid',       //门店仓库id
     * ]
     */
    public function checkByShop($bonus,$param){
        $shopping_type_info=explode(",",$bonus['shopping_type_info']);
        if($bonus['shopping_type']!=0 && ($bonus['shopping_type']!=$param['shoppingType'] || $bonus['shopping_type']==$param['shoppingType'] && 2==$param['shoppingType'] && !in_array($param['wid'],$shopping_type_info) && $bonus['shopping_type_info']!='0')){
            if($bonus['shopping_type']=='1'){
                $this->remark[] = "仅送货到家可用";
            }else if($bonus['shopping_type']=='2'){

                if(!in_array($param['wid'],$shopping_type_info) || $param['shoppingType']==1 && $bonus['shopping_type_info']!=0){
                    $shopping_type_store=config("custom.shop_info_list");

                    $shopping_type_info_arr=array();
                    foreach($shopping_type_store as $item){
                        if(in_array($item['wid'],$shopping_type_info)){
                            $shopping_type_info_arr[]=$item['name'];
                        }
                    }
                    $shopping_type_info=implode("、",$shopping_type_info_arr);
                    $this->remark[] = "仅限".$shopping_type_info."可用";
                }else{
                    $this->remark[] = "仅限到店自提可用";
                }
            }

            $this->use_flag = false;
        }
    }

    /**
     * 获取不符合条件的商品
     * @param $cart_goods_info
     * @param $type
     * @param $type_id
     * @param $include_promotion
     * @return mixed
     */
    private function getBonusMismatchGoods($cart_goods_info,$type,$type_id,$include_promotion){
        switch ($type){
            case 'cat_id' :
                $sub_cate_list = $this->categoryService->getAllSubCateId($type_id);
                foreach($cart_goods_info as $key=>$val){
                    if(in_array($val[$type],$sub_cate_list) && ($include_promotion || $val['giving']!=4)){
                        unset($cart_goods_info[$key]);
                    }
                }
            break;
            case 'brand_id' :
            case 'goods_id' :
                foreach($cart_goods_info as $key=>$val){
                    if($val[$type]==$type_id && ($include_promotion || $val['giving']!=4)){
                        unset($cart_goods_info[$key]);
                    }
                }
            break;
        }
        return $cart_goods_info;
    }

    /**
     * 统计符合红包条件的商品总价
     * @param $bouns_cart_goods_exlist
     * @param $goods_amount
     * @return mixed
     */
    private function getBounsGoodsTotalPrice($bouns_cart_goods_exlist,$goods_amount){
        foreach($bouns_cart_goods_exlist as $key=>$goods){
            $goods_amount-=$goods['goods_price']*$goods['goods_number'];
        }
        return $goods_amount;
    }


    /**
     * 检查是否符合配送以及付款时间限制
     * @param $bonus
     * @param $param = [
     *  'date'=>['best_time_start'=>$best_time_start,'best_time'=>$best_time]
     * ]
     */
    public function checkByPlaceAndShippingDate($bonus,$param){
        if(empty($param['date'])){
            return;
        }
        if(!empty($bonus['place_order_start_date']) && !empty($bonus['place_order_end_date']) && !empty($bonus['shipping_start_date']) && !empty($bonus['shipping_end_date'])){
            $date_param = $param['date'];
            $bonus_place_order_start_date = convert_to_time($bonus['place_order_start_date']);
            $bonus_place_order_end_date = convert_to_time($bonus['place_order_end_date']);
            $bonus_shipping_start_date = convert_to_time($bonus['shipping_start_date']);
            $bonus_shipping_end_date = convert_to_time($bonus['shipping_end_date']);
            //当前的时间戳
            $current_time = local_to_time();
            //当前日期
            $current_date = date('Y-m-d',$current_time);
            //当前日期时间
            $current_HS = intval(date('Hi',$current_time));
            //获取配送日期
            $shipping_date = date('Y-m-d',$date_param['best_time_start']);
            //获取配送时间范围
            $shipping_start_date = intval(date('Hi',$date_param['best_time_start']));
            $shipping_end_date = intval(date('Hi',$date_param['best_time']));

            if($shipping_start_date >= $bonus['shipping_start_date'] && $shipping_end_date <= $bonus['shipping_end_date']){
                $out_of_shipping_time = false;
            }else{
                $out_of_shipping_time = true;
            }

            if($current_HS<$bonus['place_order_start_date'] || $current_HS>$bonus['place_order_end_date']){
                $this->remark[] = "该红包仅限在".$bonus_place_order_start_date."-".$bonus_place_order_end_date."下单可用";
                $this->use_flag = false;
            }

            if(!empty($date_param)){
                //不是当天配送或者超出配送时间范围
                if($current_date!=$shipping_date || $out_of_shipping_time){
                    $this->remark[] = "该红包仅限在选择配送时间为今日".$bonus_shipping_start_date."-".$bonus_shipping_end_date."可用";
                    $this->use_flag = false;
                }
            }else{
                $this->remark[] = "该红包仅限在选择配送时间为今日".$bonus_shipping_start_date."-".$bonus_shipping_end_date."可用";
                $this->use_flag = false;
            }
        }
    }

    /**
     * 红包设置为已使用
     * @author yangzhic
     * @param int $bonusId
     * @param array $param
     * @return mixed
     */
    public function useBonus(int $bonusId,array $param){
        $param['used_time'] = gm_time();
        return $this->userBonusRepository->useBonus($bonusId,$param);
    }

}